﻿
using AppSocketModel;
using AppSocketService.Location;
using BCGPSCommon;
using BCGPSMongoData;
using System;
using System.Collections.Concurrent;
using System.Threading;

namespace AppSocketService.GPS
{
    public class GpsDataService : IGpsDataService
    {
        /// <summary>
        /// 任务的容器
        /// </summary>
        public static ConcurrentQueue<string> gpsDataQueue = new ConcurrentQueue<string>();

        private MongoDBCommand<GpsInfoDto> mongoCommand = null;

        public Thread thread { set; get; }

        /// <summary>
        /// 线程运行
        /// </summary>
        public bool IsThreadRun { set; get; }

        public GpsDataService()
        {
            IsThreadRun = true;
            thread = new Thread(Split);
            thread.IsBackground = true;
            thread.Start();
        } 
        #region 分解数据
        public void Split()
        {
            string msg = string.Empty;
            while (IsThreadRun)
            {
                msg = string.Empty;
                gpsDataQueue?.TryDequeue(out msg);

                if (string.IsNullOrWhiteSpace(msg))
                {
                    Thread.Sleep(10);
                    continue;
                }

                GpsInfoDto gpsInfoDto = new GpsInfoDto();

                //推荐的定位信息
                if (msg.Contains("GNRMC"))
                {
                    var fPacketOne = msg.Split('$');

                    if (fPacketOne.Length < 4)
                        return;

                    gpsInfoDto.Imei = fPacketOne[1];
                    gpsInfoDto.Phone = fPacketOne[2];
                    string[] fPacketTwo = fPacketOne[3].Split(',');
                    if (fPacketTwo.Length == 13)
                    {
                        //有效数据
                        if (fPacketTwo[2] == "A")
                        {

                            gpsInfoDto.GpsTime = new DateTime(
                                int.Parse(DateTime.Now.Year.ToString().Substring(0, 2) + fPacketTwo[9].Substring(4, 2)),
                                int.Parse(fPacketTwo[9].Substring(2, 2)),
                                int.Parse(fPacketTwo[9].Substring(0, 2)),
                                int.Parse(fPacketTwo[1].Substring(0, 2)),
                                int.Parse(fPacketTwo[1].Substring(2, 2)),
                                int.Parse(fPacketTwo[1].Substring(4, 2))).AddHours(8);
                            gpsInfoDto.SysTime = DateTime.Now;
                            gpsInfoDto.ServerTime = DateTime.Now;
                            gpsInfoDto.Lat = double.Parse(fPacketTwo[3]);
                            gpsInfoDto.Lng = double.Parse(fPacketTwo[5]);
                            gpsInfoDto.Course = double.Parse(fPacketTwo[8]);
                            gpsInfoDto.Speed = double.Parse(fPacketTwo[7]);

                            Save(gpsInfoDto);
                        }
                    }
                }
            }
            Console.WriteLine(thread.ManagedThreadId + "  is Over ");
        }

        #endregion

        #region 保存数据

        private void Save(GpsInfoDto gpsInfoDto)
        {
            SaveHistory(gpsInfoDto);
            SaveAccountLocation(gpsInfoDto);
            SaveMemory(gpsInfoDto);
        }

        //保存单个gps历史记录
        private void SaveHistory(GpsInfoDto gpsInfoDto)
        {
            Console.WriteLine(JsonExtensions.ObjectToJson(gpsInfoDto));
            mongoCommand = new MongoDBCommand<GpsInfoDto>(gpsInfoDto.Imei);
            mongoCommand.InsertDocumentAsync(gpsInfoDto);
        }

        //更新账户GPS位置表
        private void SaveAccountLocation(GpsInfoDto gpsInfoDto)
        {
            if (Memory.Memory.DictImeiAccountCode.ContainsKey(gpsInfoDto.Imei))
            {
                foreach (var item in Memory.Memory.DictImeiAccountCode[gpsInfoDto.Imei])
                {
                    new LocationService(item).UpdateGpsInfo(gpsInfoDto);
                }
            }
        }

        //更新内存GPS位置字典
        private void SaveMemory(GpsInfoDto gpsInfoDto)
        {
            if(Memory.Memory.DictLocation.ContainsKey(gpsInfoDto.Imei))
            {
                Memory.Memory.DictLocation[gpsInfoDto.Imei] = gpsInfoDto.GetLocationDto();
            }
            else
            {
                Memory.Memory.DictLocation.Add(gpsInfoDto.Imei, gpsInfoDto.GetLocationDto());
            }
        }
        #endregion
    }
}
